package com.qf.service.impl;


import com.alibaba.fastjson.JSONObject;
import com.qf.dao.LiveUserRepository;
import com.qf.pojo.RedisKey;
import com.qf.pojo.reqVo.UserReq;
import com.qf.pojo.respVo.BaseResp;
import com.qf.pojo.vo.LiveUser;
import com.qf.service.UserService;
import com.qf.utils.JwtUtils;
import com.qf.utils.MD5Utils;
import io.rong.RongCloud;
import io.rong.methods.user.User;
import io.rong.models.response.TokenResult;
import io.rong.models.user.UserModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class UserServiceImpl implements UserService {

    //日志
    private static Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);

    @Autowired
    LiveUserRepository liveUserRepository;



    @Autowired
    JwtUtils jwtUtils;

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    RabbitTemplate rabbitTemplate;

    @Override
    public BaseResp validataEmail(String email) {
        //1.记录日志
        logger.debug("进入邮箱的认证，邮箱号未：{}"+email);
        if ( email==null||email.trim().isEmpty()){
            return new BaseResp().errorParams();
        }

        //2.去数据库查询改邮箱是否存在
        LiveUser byEmail = liveUserRepository.findByEmail(email);
        if (byEmail!=null){
            return new BaseResp(0,"邮箱被占用！请更换",null,null);
        }

        return new BaseResp().success();
    }

    @Override
    public BaseResp validataloginName(UserReq userReq) {
        logger.debug("进入用户名验证。用户名为：{}"+userReq.getLoginName());
        if (userReq.getLoginName()==null||userReq.getLoginName().trim().isEmpty()){
            return new BaseResp().errorParams();
        }
        //进入数据库进行查询
      LiveUser liveUser =  liveUserRepository.findByLoginName(userReq.getLoginName());
        if (liveUser!=null){
            return new BaseResp(0,"用户名已存在！",null,null);
        }
        return new BaseResp().success();
    }

    @Override
    public BaseResp sendMail(String email) {
        /**
         * 1.邮件发送的三种情况
         *  1.1 该用户已经被注册过，返回不允许发送
         *  1.2 该用户的邮箱 第一次发送
         *  1.3 该用户的邮箱 已经发送过，但是未注册成功！
         */
        logger.debug("进入邮件的发送。邮箱号为：{}"+email);
        if (email==null||email.trim().isEmpty()){
            return new BaseResp().errorParams();
        }
        //1.第一个判断
        LiveUser byEmail = liveUserRepository.findByEmail(email);
        if (byEmail!=null){
            return new BaseResp(0,"改邮箱已被注册！",null,null);
        }
        Map map = new HashMap();
        map.put("email",email);
        rabbitTemplate.convertAndSend("","email-queue",map);
        return new BaseResp().success();
    }

    @Override
    public BaseResp registry(UserReq userReq) {
        //验证
        //1.记录日志
        logger.debug("进入到注册逻辑：{}"+userReq);
        if ( userReq.getEmail()==null||userReq.getEmail().trim().isEmpty()){
            return new BaseResp().errorParams();
        }

        //2.去数据库查询改邮箱是否存在
        LiveUser byEmail = liveUserRepository.findByEmail(userReq.getEmail());
        if (byEmail!=null){
            return new BaseResp(0,"邮箱被占用！请更换",null,null);
        }
        if (userReq.getLoginName()==null||userReq.getLoginName().trim().isEmpty()){
            return new BaseResp().errorParams();
        }
        //进入数据库进行查询
        LiveUser liveUser =  liveUserRepository.findByLoginName(userReq.getLoginName());
        if (liveUser!=null){
            return new BaseResp(0,"用户名已存在！",null,null);
        }
        if (userReq.getPassword()==null||userReq.getPassword().trim().isEmpty()){
            return new BaseResp().errorParams();
        }
        if (userReq.getCode()==null||userReq.getCode().trim().isEmpty()){
            return new BaseResp().errorParams();
        }
        //判断验证码是否一致
        //ValadataNumber byEmail1 = valadataRespository.findByEmail(userReq.getEmail());
        Boolean aBoolean = redisTemplate.hasKey(RedisKey.CODE + userReq.getEmail());
        if (!aBoolean){
            return new BaseResp(0,"改邮箱未发送验证码！请先发送！",null,null);
        }
        Object o = redisTemplate.opsForValue().get(RedisKey.CODE + userReq.getEmail());
        if (!o.toString().equals(userReq.getCode())){
            return new BaseResp(0,"验证码比较失败！",null,null);
        }
        //进行注册的操作
        LiveUser liveUser1 = new LiveUser();
        //进行密码的加密操作

        String md5Password = MD5Utils.md5(userReq.getPassword());
        userReq.setPassword(md5Password);
        BeanUtils.copyProperties(userReq,liveUser1);
        liveUser1.setCreateTime(new Date());
        //获取融云唯一用户的token信息
        //融云的key值
        String appKey = "8luwapkv8wxcl";
        //融云的密码
        String appSecret = "I4BB9FgbDFT";

        RongCloud rongCloud = RongCloud.getInstance(appKey, appSecret);
        User user = rongCloud.user;

        /**
         *
         * 注册用户，生成用户在融云的唯一身份标识 Token
         */

        LiveUser save = liveUserRepository.save(liveUser1);
        UserModel userModel = new UserModel()
                //设置唯一标识
                .setId(save.getUserId().toString())
                //设置用户名
                .setName(userReq.getLoginName())
                //设置头像
                .setPortrait("http://www.rongcloud.cn/images/logo.png");
        TokenResult result = null;
        try {
            result = user.register(userModel);
        } catch (Exception exception) {
            exception.printStackTrace();
        }
        System.out.println("getToken:  " + result.toString());
        liveUser1.setRongToken(result.getToken());
        liveUserRepository.saveAndFlush(liveUser1);
        //用户注册成功后，修改验证码的状态码
//        byEmail1.setStatus(1);
//        valadataRespository.saveAndFlush(byEmail1);
        return new BaseResp(1,"用户注册成功！",null,null);
    }

    @Override
    public BaseResp login(UserReq userReq) {
        //非空验证
        if (userReq.getLoginName()==null||userReq.getLoginName().trim().isEmpty()||userReq.getPassword()==null||userReq.getPassword().trim().isEmpty()){
            return new BaseResp().errorParams();
        }
        //使用用户名查询
        LiveUser byLoginName = liveUserRepository.findByLoginName(userReq.getLoginName());
        if (byLoginName==null){
            return new BaseResp(0,"用户不存在！",null,null);
        }
        //比对密码
        String md5Pass = MD5Utils.md5(userReq.getPassword());
        if (!byLoginName.getPassword().equals(md5Pass)){
            return new BaseResp(0,"密码错误！",null,null);
        }
        //签发jwt的令牌
        Map map = new HashMap<>();
        map.put("id",byLoginName.getUserId());
        map.put("name",byLoginName.getLoginName());
        map.put("rongToken",byLoginName.getRongToken());
        String token = jwtUtils.signToken(map);
        //为了token的安全性，我们需要将token放置在redis中，返回前台改key值
        UUID uuid = UUID.randomUUID();
        //用户存活时长为5分钟
        redisTemplate.opsForValue().set(uuid.toString(),token,30,TimeUnit.MINUTES);
        //同时将用户信息存储在redis中，进行判定用户是否登录，如果用户未登录，则可以发送成功！后续可添加 发送离线消息
        //声明一个在线用户列表，hash结构，后续用户退出时，从Redis中移除
        redisTemplate.opsForHash().put(RedisKey.USERLOGIN,byLoginName.getUserId().toString(),byLoginName);
        return new BaseResp(1,"登录成功！",uuid.toString(),null);
    }

    @Override
    public BaseResp findUserByToken(HttpServletRequest request) {
        //从request中获取cookie
        Cookie[] cookies = request.getCookies();
        if (cookies==null){
            return new BaseResp(0,"未登录！",null,null);
        }
        String token =null;
        for (Cookie cook:cookies
             ) {
            if (cook.getName().equals("token")){
                token=cook.getValue();
            }
        }
        //判断
        if (token==null){
            return new BaseResp(0,"未登录！",null,null);
        }
        //从redis获取 jwt token
        Boolean aBoolean = redisTemplate.hasKey(token);
        if (!aBoolean){
            return new BaseResp(0,"登录失效！",null,null);
        }
        Object o = redisTemplate.opsForValue().get(token);
        //使用jwt utils解密
        Integer verfiy = jwtUtils.verfiy(o.toString());
        //通过id获取到该用户
        Optional<LiveUser> byId = liveUserRepository.findById(verfiy);
        if (!byId.isPresent()){
            return new BaseResp(0,"没有该用户！",null,null);
        }
        LiveUser liveUser = new LiveUser();
        liveUser.setLoginName(byId.get().getLoginName());
        liveUser.setPic(byId.get().getPic());
        liveUser.setRongToken(byId.get().getRongToken());
        liveUser.setUserId(byId.get().getUserId());

        return new BaseResp(1,"获取成功！",liveUser,null);
    }
}
